﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Word;
using Microsoft.Office.Tools.Word.Extensions;
using biolit_config;
using OntologyCache;
using System.Windows.Forms;
using System.IO;
using System.Xml.Schema;
using System.Threading;
using System.Xml.XPath;
using Word = Microsoft.Office.Interop.Word;
using System.Diagnostics;
using Microsoft.Office.Tools;
using System.Text.RegularExpressions;
using UCSD_BioLit.Properties;

namespace UCSD_BioLit
{
    public partial class BioLitRibbon : OfficeRibbon
    {
        public BioLitRibbon()
        {
            InitializeComponent();
        }
        private Microsoft.Office.Tools.Word.Action UniprotAction;
        private Microsoft.Office.Tools.Word.Action NCBIAction;
        OntList ontologyList = null;
        XPathNavigator _navigator;
        XPathDocument _docNavigator;
        XPathNodeIterator _nodeIterator;
        string presentVersion = string.Empty;

        /// <summary>
        /// class name for exception title.
        /// </summary>
        private const string ExceptionTitle = "BioLitRibbon.cs";

        /// <summary>
        /// local file.
        /// </summary>
        private const string LocalString = "Local File";

        /// <summary>
        /// download url.
        /// </summary>
        private const string DownloadURL = "http://rest.bioontology.org/bioportal/ontologies/";

        /// <summary>
        /// XPath string.
        /// </summary>
        private const string NodePath = "/success/data/ontologyBean";

        /// <summary>
        /// version number.
        /// </summary>
        private const string VersionNumber = "versionNumber";

        /// <summary>
        /// display label.
        /// </summary>
        private const string DisplayLabel = "displayLabel";

        /// <summary>
        /// id label.
        /// </summary>
        private const string IDLabel = "id";

        /// <summary>
        /// rest web services.
        /// </summary>
        private const string SourceName = "Rest WebServices";

        private void BioLitRibbon_Load(object sender, RibbonUIEventArgs e)
        {
            ConfigSettings cs = Biolit_Settings.Settings;
            if (cs == null)
                chkUpdate.Checked = true;
            else
                chkUpdate.Checked = cs.ontologiesUpdate;
            if (chkUpdate.Checked)
            {
                Thread thread = new Thread(this.BackgroundOntologyDownload);
                thread.IsBackground = true;
                thread.Start();
                while (thread.IsAlive == true)
                {
                    Application.DoEvents();
                }
            }
        }

        private void btnConfig_Click_1(object sender, RibbonControlEventArgs e)
        {
            ThisAddIn add = Globals.ThisAddIn;

            SettingsDialog settingsDialog = new SettingsDialog();

            settingsDialog.ShowDialog();

            if (settingsDialog.needToDownloadOntologies == true)
            {
                List<OntList> onList = new List<OntList>();
                string[] filePaths = Directory.GetFiles(Biolit_Settings.Settings.OBO_DWNLDS);
                if (filePaths != null)
                {
                    foreach (OntList onlist in Globals.ThisAddIn.m_SelectedOntologies)
                    {
                        if (!onlist.Source.Equals(LocalString, StringComparison.CurrentCultureIgnoreCase))
                        {
                            bool fileCopy = true;
                            foreach (string file in filePaths)
                            {
                                string ontFileName = file.Substring(file.LastIndexOf(@"\") + 1);
                                if (ontFileName.ToLower().Equals(onlist.Name.ToLower() + "." + onlist.Format.ToLower()))
                                {
                                    fileCopy = false;
                                    break;
                                }
                            }
                            if (Biolit_Settings.Settings.failedOnt != null)
                            {
                                foreach (OntList ontFailedList in Biolit_Settings.Settings.failedOnt)
                                {
                                    if (ontFailedList.Name.ToLower().Equals(onlist.Name.ToLower()))
                                    {
                                        fileCopy = false;
                                        break;
                                    }
                                }
                            }
                            if (fileCopy)
                                onList.Add(onlist);
                        }
                    }
                }
                if (onList.Count <= 0) return;
                DownLoadProgress dlp = new DownLoadProgress();
                dlp.Downloads = onList;
                dlp.Show();
                dlp.DoDownload();
            }

            if (true == Globals.ThisAddIn.IsTermRecognitionOn)
            {
                foreach (var Ont in Globals.ThisAddIn.m_SelectedOntologies)
                {
                    bool Found = false;
                    foreach (var exist in add.m_Ontologies)
                    {
                        if (exist.OntologyName == Ont.Name)
                        {
                            Found = true;
                            break;
                        }

                    }
                    if (Found == false)
                    {
                        if (File.Exists(Biolit_Settings.Settings.OBO_DWNLDS + "\\" + Ont.Name + ".dat"))
                        {
                            string filename = Biolit_Settings.Settings.OBO_DWNLDS + "\\" + Ont.Name + ".dat";
                            OntologyInfo thetags = CacheManager.LoadTagsFromCache(filename, true, Ont.Name);
                            if (thetags != null)
                            {
                                thetags.OntologyName = Ont.Name;
                                add.m_Ontologies.Add(thetags);
                                AttachOntologytoSmartTagTerms(thetags);
                            }
                        }
                    }
                }
            }
        }

        private static string _matchingID;

        private static bool MatchingID(OntList ontology)
        {
            return (ontology.ID.Equals(_matchingID));
        }

        private static string _matchingName;

        private static bool MatchingName(OntList ontology)
        {
            return (ontology.Name.Equals(_matchingName));
        }

        /// <summary>
        /// Method used to check for missing ontologies so that it can be prompted to user for download.
        /// </summary>
        /// <returns>returns the list of ontologies to download</returns>
        private List<OntList> GetMissingDocumentOntologies()
        {
            ThisAddIn add = Globals.ThisAddIn;
            List<OntList> DocumentOntologies = new List<OntList>();

            if (true == add.IsBiolitDoc(add.Application.ActiveDocument))
            {
                Word.ContentControls controls = add.Application.ActiveDocument.ContentControls;

                // used to retrieve controls under biolit namespace to check if the ontology name is present in the ontologies list.
                foreach (Word.ContentControl control in controls)
                {
                    if (control.Tag == null)
                    {
                        continue;
                    }

                    Guid controlId = WordCommonFuncs.ConvertToGuid(control.Tag);

                    if (controlId != null && controlId != Guid.Empty && ControlsStorage.ControlCollection.ContainsKey(controlId))
                    {
                        ControlProperties properties = ControlsStorage.ControlCollection[controlId];
                        if (properties.ControlNamespace == ThisAddIn.ONTOLOGY_NS_URI)
                        {
                            if (!string.IsNullOrEmpty(properties.PropertyList["OntName"]))
                            {
                                _matchingName = properties.PropertyList["OntName"];
                                if (false == Globals.ThisAddIn.m_SelectedOntologies.Exists(MatchingName))
                                {
                                    string OntID = Biolit_Settings.Settings.FindOntologyID(properties.PropertyList["OntName"]);

                                    // remove any duplicate ontology IDs
                                    _matchingID = OntID;

                                    if (OntID != null && DocumentOntologies.Exists(MatchingID) == false)
                                    {
                                        OntList list = new OntList(properties.PropertyList["OntName"], OntID, "", "OBO", "");
                                        DocumentOntologies.Add(list);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return DocumentOntologies;
        }

        private CustSmartTagAction[] GetCustomActions()
        {
            ThisAddIn add = Globals.ThisAddIn;
            CustSmartTagAction[] Actions = new CustSmartTagAction[7];

            // View in browser
            Actions[0] = new CustSmartTagAction();
            Actions[0].m_TagID = -1;
            Actions[0].Caption = Resources.ViewInOntologyBrowserString;
            Actions[0].Click += (object sender, ActionEventArgs e) =>
            {
                DocumentWrapper wrDoc = Globals.ThisAddIn.FindActiveWrapper();
                wrDoc.LookupTerm(e.Text);
            };

            //Add mark up to all such terms
            Actions[1] = new CustSmartTagAction();
            Actions[1].m_TagID = -2;
            Actions[1].Caption = Resources.ApplyMarkupToAllString;
            Actions[1].Click += new ActionClickEventHandler(add.m_sth.ApplyMarkupToAllInstances);

            for (int i = 2; i < 7; ++i)
            {
                Actions[i] = new CustSmartTagAction();
                Actions[i].m_TagID = i - 2;
                Actions[i].BeforeCaptionShow += new BeforeCaptionShowEventHandler(add.m_sth.AddMarkup_BeforeCaptionShow);
                Actions[i].Click += new ActionClickEventHandler(add.m_sth.AddMarkup_Click);

            }

            return Actions;

        }

        private void AttachOntologytoSmartTagTerms(OntologyCache.OntologyInfo OntInfo)
        {
            ThisAddIn add = Globals.ThisAddIn;
            foreach (var KPPair in OntInfo.m_TermLookup)
            {
                string TermName = KPPair.Key;
                try
                {
                    if (TermName.Contains(' ') || TermName.Contains("_"))
                    {
                        add.m_BioLitTags.Expressions.Add(new Regex(@"(?i)\b" + Regex.Escape(KPPair.Key) + @"\b"));
                    }
                    else
                    {
                        // we want to recognise terms regardless of their capitalization, except for hyphenated terms

                        if (TermName.Contains('-'))
                        {
                            //hyphenated terms many times contain specific capital letters
                            add.m_BioLitTags.Terms.Add(KPPair.Key);
                        }
                        else
                        {
                            // Regex for case insensitive term recognition.
                            add.m_BioLitTags.Expressions.Add(new Regex(@"(?i)\b" + Regex.Escape(KPPair.Key) + @"\b"));
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message, ExceptionTitle);
                }
            }
        }
        private void FillSmartTagWithOntologyTerms()
        {
            ThisAddIn add = Globals.ThisAddIn;

            // First Load all OBO selected by user
            if (Biolit_Settings.Settings != null)
            {
                try
                {
                    string ontologiesFolderPath = Biolit_Settings.Settings.OBO_DWNLDS;
                    // create the list of selected ontologies based on the fileson disk
                    if (Directory.Exists(ontologiesFolderPath) == true)
                    {
                        string[] ontologyFiles = Directory.GetFiles(ontologiesFolderPath, "*.dat");
                        int index = 0;

                        if (ontologyFiles.Count() != 0)
                        {
                            Globals.ThisAddIn.m_SelectedOntologies = new List<OntList>();
                        }

                        foreach (string filename in ontologyFiles)
                        {
                            int position = filename.LastIndexOf('\\');
                            if (position != -1)
                            {
                                string ontFileName = filename.Substring(position + 1);
                                string ontologyName = ontFileName.Remove(ontFileName.LastIndexOf('.'));
                                OntList getOntology = GetOntology(ontologyName);

                                if (getOntology != null)
                                    Globals.ThisAddIn.m_SelectedOntologies.Add(getOntology);
                                OntologyInfo thetags = CacheManager.LoadTagsFromCache(filename, true, ontologyName);
                                if (thetags != null)
                                {
                                    thetags.OntologyName = ontologyName;// Must do this here for down stream code that needs access to this 
                                    add.m_Ontologies.Add(thetags);
                                }
                            }
                        }
                        if (Globals.ThisAddIn.m_SelectedOntologies != null)
                        {
                            if (Biolit_Settings.Settings.failedOnt != null && Biolit_Settings.Settings.failedOnt.Count() > 0)
                            {
                                foreach (OntList failedOntList in Biolit_Settings.Settings.failedOnt)
                                {
                                    if (false == AlreadyExists(failedOntList))
                                        Globals.ThisAddIn.m_SelectedOntologies.Add(failedOntList);
                                }
                            }
                        }
                    }
                    else
                    {
                        Directory.CreateDirectory(ontologiesFolderPath);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message, ExceptionTitle);
                };
            }

            // Load the custom OBO if it exists
            OntologyInfo Customtags = CacheManager.LoadNonCachedTags("Custom", Biolit_Settings.Settings.OBO_DWNLDS + "\\" + "Custom.OBO");
            if (Customtags != null)
            {
                Customtags.OntologyName = "Custom";
                add.m_Ontologies.Add(Customtags);
            }



            foreach (OntologyCache.OntologyInfo OntInfo in Globals.ThisAddIn.m_Ontologies)
            {
                AttachOntologytoSmartTagTerms(OntInfo);
            }
        }

        private OntList GetOntology(string ontologyName)
        {
            OntList ontologyList = null;
            bool localFile = false;
            if (Biolit_Settings.Settings.AvailableOntologies != null && Biolit_Settings.Settings.AvailableOntologies.Count() > 0)
            {
                foreach (OntList onlist in Biolit_Settings.Settings.AvailableOntologies)
                {

                    if (Biolit_Settings.Settings.DownloadedOntologies != null)
                    {
                        foreach (biolit_config.DownloadHistory downloadHistory in Biolit_Settings.Settings.DownloadedOntologies)
                        {
                            if (downloadHistory._OntologyName.Equals(ontologyName, StringComparison.CurrentCultureIgnoreCase))
                            {
                                if (downloadHistory._Source.Equals(LocalString, StringComparison.CurrentCultureIgnoreCase))
                                {
                                    localFile = true;
                                    ontologyList = new OntList(downloadHistory._OntologyName, string.Empty, string.Empty, downloadHistory._Format, downloadHistory._Source);
                                    break;
                                }
                            }
                        }
                    }
                    if (localFile)
                        return ontologyList;
                    else
                    {
                        if (onlist.Name.Equals(ontologyName, StringComparison.CurrentCultureIgnoreCase))
                        {
                            ontologyList = onlist;
                            break;
                        }
                    }
                }
                return ontologyList;
            }
            return null;
        }

        private bool AlreadyExists(OntList ontList)
        {
            Boolean alreadyInSelectedList = false;
            if (Globals.ThisAddIn.m_SelectedOntologies != null && Globals.ThisAddIn.m_SelectedOntologies.Count > 0)
            {
                foreach (OntList onlist in Globals.ThisAddIn.m_SelectedOntologies)
                {
                    if (ontList.Name.Equals(onlist.Name, StringComparison.CurrentCultureIgnoreCase))
                    {
                        alreadyInSelectedList = true;
                        break;
                    }
                }
            }
            return alreadyInSelectedList;
        }
        private void AttachSchema()
        {
            try
            {
                ThisAddIn add = Globals.ThisAddIn;
                object activeDoc = add.Application.ActiveDocument;
                XmlSchemaSet schemaSet = new XmlSchemaSet();
                foreach (XmlSchema schema in schemaSet.Schemas())
                {
                    if (schema.TargetNamespace == ThisAddIn.BIOLIT_NS_URI || schema.TargetNamespace == ThisAddIn.ONTOLOGY_NS_URI || schema.TargetNamespace == ThisAddIn.DB_NS_URI)
                    {
                        schemaSet.Remove(schema);
                    }
                }
                add.schemaRef.AttachToDocument(ref activeDoc);
                add.dbSchemaRef.AttachToDocument(ref activeDoc);
                add.ontSchemaRef.AttachToDocument(ref activeDoc);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message, ExceptionTitle);
            }

        }

        private void AddCustTags()
        {

            AddNCBITag();
            AddPDBTag();
            AddUniprotTag();
        }

        public void ParseOn()
        {
            Word.WdCursorType saveRestoreCursor = Globals.ThisAddIn.Application.System.Cursor;
            Globals.ThisAddIn.Application.System.Cursor = Word.WdCursorType.wdCursorWait;

            tbHighlight.Checked = true;
            ThisAddIn add = Globals.ThisAddIn;

            if (add.m_BioLitTags == null)
            {
                add.m_BioLitTags = new SmartTag("BioLitTags#Term", Properties.Resources.BIOLIT_STRING);
                this.FillSmartTagWithOntologyTerms();
                add.m_BioLitTags.Actions = GetCustomActions();
                AddCustTags();
                add.VstoSmartTags.Add(add.m_BioLitTags);

                // there are some scenarios where the fist document you get when you open word does not raise any events( New / Open etc)
                // so add this document to our wrapper 
                AttachSchema();
                add.FindWrapper(add.Application.ActiveDocument, true); // this will cause this document to get wrapped if it does not exist
            }

            // to check for missing ontologies.
            List<OntList> DocumentOntologies = GetMissingDocumentOntologies();
            if (DocumentOntologies.Count > 0)
            {
                MissingOntologies mo = new MissingOntologies();
                mo.Ontologies = DocumentOntologies.ToArray();
                mo.ShowDialog();
                foreach (var Ont in DocumentOntologies)
                {
                    bool Found = false;
                    foreach (var exist in add.m_Ontologies)
                    {
                        if (exist.OntologyName == Ont.Name)
                        {
                            Found = true;
                            break;
                        }

                    }
                    if (Found == false)
                    {
                        if (File.Exists(Biolit_Settings.Settings.OBO_DWNLDS + "\\" + Ont.Name + ".dat"))
                        {
                            string filename = Biolit_Settings.Settings.OBO_DWNLDS + "\\" + Ont.Name + ".dat";
                            OntologyInfo thetags = CacheManager.LoadTagsFromCache(filename, true, Ont.Name);
                            if (thetags != null)
                            {
                                thetags.OntologyName = Ont.Name;
                                add.m_Ontologies.Add(thetags);
                                Globals.ThisAddIn.m_SelectedOntologies.Add(Ont);
                                AttachOntologytoSmartTagTerms(thetags);
                            }
                        }
                    }
                }
            }

            this.tbParse.Checked = true;

            // ensure that smarttags are enabled, the author may not know where/how to do this
            if (!add.Application.Options.LabelSmartTags)
            {
                add.Application.Options.LabelSmartTags = true;
            }

            // force a re-check of the document, in case there is already text on it
            add.Application.ActiveDocument.RecheckSmartTags();

            Globals.ThisAddIn.IsTermRecognitionOn = true;
            Globals.ThisAddIn.Application.System.Cursor = saveRestoreCursor;
        }

        private void AddTag(string tag, string Caption, string[] RegEx, ref SmartTag st, ActionClickEventHandler aceh)
        {
            ThisAddIn add = Globals.ThisAddIn;
            if (null == st)
            {
                st = new SmartTag("BioLitTags#" + tag, Properties.Resources.BIOLIT_STRING);
            }
            Microsoft.Office.Tools.Word.Action act = new Microsoft.Office.Tools.Word.Action(Caption);
            act.Click += aceh;
            st.Actions = new ActionBase[1];
            st.Actions[0] = act;
            int Len = RegEx.Length;
            for (int i = 0; i < Len; ++i)
            {
                st.Expressions.Add(new Regex(RegEx[i]));
            }
            add.VstoSmartTags.Add(st);


        }

        private void AddUniprot()
        {
            ThisAddIn add = Globals.ThisAddIn;
            SmartTag UnitprotTag = new SmartTag(ThisAddIn.DB_NS_URI + @"#tag2", Properties.Resources.BIOLIT_STRING);
            UnitprotTag.Expressions.Add(new Regex(
                @"\s[A-Z]{1}[0-9][a-zA-Z][0-9a-zA-Z]{2}[0-9]"));
            UnitprotTag.Expressions.Add(new Regex(
                            @"\s[A|O|P|Q]{1}[0-9][0-9a-zA-Z]{3}[0-9]"));
            UniprotAction = new Microsoft.Office.Tools.Word.Action(Properties.Resources.ADD_UNIPROT_STRING);
            UnitprotTag.Actions = new Microsoft.Office.Tools.Word.Action[] { UniprotAction };
            add.VstoSmartTags.Add(UnitprotTag);
            UniprotAction.Click += new
                ActionClickEventHandler(
                UniProtAction_Click);

        }
        private void UniProtAction_Click(object sender, ActionEventArgs e)
        {
            ThisAddIn add = Globals.ThisAddIn;
            add.m_sth.UniprotMarkup_Click(sender, e);
        }
        private void AddNCBI()
        {
            ThisAddIn add = Globals.ThisAddIn;
            SmartTag NCBITag = new SmartTag(ThisAddIn.DB_NS_URI + @"#tag4", Properties.Resources.BIOLIT_STRING);
            NCBITag.Expressions.Add(new Regex(
                @"\s[A|B|C|D|E|F|G|H|I|J|K|L|M|N|S|T|U|V|W|X|Y|Z]\d{5}"));
            NCBITag.Expressions.Add(new Regex(
                            @"\s[A|B|C|D|E|F|G|H|I|J|K|L|M|N|S|T|U|V|W|X|Y|Z][A-Z]\d{6}"));
            NCBITag.Expressions.Add(new Regex(
                            @"\s[A|B|C|D|E|F|G]A[A|E]\d{5}"));
            NCBITag.Expressions.Add(new Regex(
                            @"\s[A|N|X|Y|Z][C|P|M|R|W|Z|S]_\d{6,}"));
            NCBIAction = new Microsoft.Office.Tools.Word.Action(Properties.Resources.ADD_NCBI_STRING);
            NCBITag.Actions = new Microsoft.Office.Tools.Word.Action[] { NCBIAction };
            add.VstoSmartTags.Add(NCBITag);
            NCBIAction.Click += new
                ActionClickEventHandler(
                NCBIAction_Click);
        }
        private void NCBIAction_Click(object sender, ActionEventArgs e)
        {
            ThisAddIn add = Globals.ThisAddIn;
            add.m_sth.NCBIMarkup_Click(sender, e);
        }
        private void AddNCBITag()
        {
            ThisAddIn add = Globals.ThisAddIn;
            if (Biolit_Settings.Settings != null)
            {
                if (true == Biolit_Settings.Settings.NCBI)
                    AddNCBI();
            }
        }

        private void AddPDBTag()
        {
            ThisAddIn add = Globals.ThisAddIn;
            if (Biolit_Settings.Settings != null)
            {
                if (true == Biolit_Settings.Settings.ProteinDataBank)
                {
                    AddTag("tag3", Properties.Resources.ADD_PDB_STRING, new string[1] { @"\s[1-9][a-zA-Z]{1}[a-zA-Z0-9]{2}" }, ref add.m_PDBTag, add.m_sth.PDBMarkup_Click);

                }
            }

        }
        private void AddUniprotTag()
        {
            ThisAddIn add = Globals.ThisAddIn;
            if (Biolit_Settings.Settings != null)
            {
                if (true == Biolit_Settings.Settings.UniProt)
                    AddUniprot();
            }
        }


        private void ParseOff()
        {
            try
            {
                ThisAddIn add = Globals.ThisAddIn;
                if (add.m_BioLitTags != null)
                {
                    if (add.VstoSmartTags.Count > 0)
                    {   
                        add.VstoSmartTags.Remove(add.m_BioLitTags);
                    }
                }
                if (add.m_UniprotTag != null)
                    RemoveTag(add.m_UniprotTag);
                if (add.m_PDBTag != null)
                    RemoveTag(add.m_PDBTag);
                if (add.m_NCBITag != null)
                    RemoveTag(add.m_NCBITag);
                if (add.Application.Options.LabelSmartTags)
                {
                    add.Application.Options.LabelSmartTags = false;
                }
                this.tbParse.Checked = false;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message, ExceptionTitle);
            }
        }

        void RemoveTag(SmartTag st)
        {
            ThisAddIn add = Globals.ThisAddIn;
            if (st != null)
            {
                if (add.VstoSmartTags.Count > 0)
                    add.VstoSmartTags.Remove(st);
                st = null;

            }
        }

        private void SetHighLighting()
        {
            SetMarkUpColor(Word.WdColorIndex.wdYellow);
        }

        private void UndoHighlighting()
        {
            SetMarkUpColor(Word.WdColorIndex.wdAuto);
        }

        /// <summary>
        /// Method for highlighting/remove highlighting of the ontology markup tags.
        /// </summary>
        /// <param name="colorToSet">highlight color</param>
        private void SetMarkUpColor(Word.WdColorIndex colorToSet)
        {
            try
            {
                // get all the content controls under the biolit/ontology/DB namespace are only highlighted.
                Word.ContentControls nodes = Globals.ThisAddIn.Application.ActiveDocument.ContentControls;
                foreach (Word.ContentControl node in nodes)
                {
                    Guid controlId = WordCommonFuncs.ConvertToGuid(node.Tag);
                    if (controlId != null && controlId != Guid.Empty && ControlsStorage.ControlCollection.ContainsKey(controlId))
                    {
                        ControlProperties property = ControlsStorage.ControlCollection[controlId];
                        if (property.ControlNamespace == ThisAddIn.BIOLIT_NS_URI || property.ControlNamespace == ThisAddIn.ONTOLOGY_NS_URI || property.ControlNamespace == ThisAddIn.DB_NS_URI)
                        {
                            node.Range.HighlightColorIndex = colorToSet;

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message, ExceptionTitle);
            }
        }
        // Show Custom Task Pane
        private void button2_Click(object sender, RibbonControlEventArgs e)
        {
            DocumentWrapper dw = Globals.ThisAddIn.FindWrapper(Globals.ThisAddIn.Application.ActiveDocument, true);
            if (dw != null)
            {
                dw.TaskPane.Visible = true;
            }
        }

        private void btnOntoBrowser_Click(object sender, RibbonControlEventArgs e)
        {
            DocumentWrapper dw = Globals.ThisAddIn.FindWrapper(Globals.ThisAddIn.Application.ActiveDocument, true);
            if (dw != null)
            {
                dw.TaskPane.Visible = true;
                dw.TaskPaneControl.TestFlow();
            }


        }

        /// <summary>
        /// delete Markup button click event handler to remove all the markup controls present in the document.
        /// </summary>
        /// <param name="sender">button object</param>
        /// <param name="e">event args</param>
        private void btnDelMarkup_Click(object sender, RibbonControlEventArgs e)
        {
            // List to store the controls which are to be deleted.
            List<Word.ContentControl> delNodes = new List<Word.ContentControl>();
            DialogResult dr = MessageBox.Show(Properties.Resources.DELETE_CONFIRMATION_MESSAGE, Properties.Resources.ONTOLOGY_MESSAGE_TITLE, MessageBoxButtons.YesNo);
            if (dr == DialogResult.Yes)
            {
                // Remove the highlighting.
                SetMarkUpColor(Word.WdColorIndex.wdAuto);

                Word.ContentControls nodes = Globals.ThisAddIn.Application.ActiveDocument.ContentControls;
                // To retrieve the controls present in biolit/DB/ontology namespaces.
                foreach (Word.ContentControl node in nodes)
                {
                    Guid controlId = WordCommonFuncs.ConvertToGuid(node.Tag);
                    if (controlId != null && controlId != Guid.Empty && ControlsStorage.ControlCollection.ContainsKey(controlId))
                    {
                        ControlProperties property = ControlsStorage.ControlCollection[controlId];

                        if (property.ControlNamespace == ThisAddIn.BIOLIT_NS_URI || property.ControlNamespace == ThisAddIn.ONTOLOGY_NS_URI || property.ControlNamespace == ThisAddIn.DB_NS_URI)
                        {
                            Word.Range controlRange = node.Range;
                            controlRange.Text = node.Range.Text;
                            delNodes.Add(node);
                        }
                    }
                }
                foreach (var X in delNodes)
                {
                    X.Delete(false);
                }
            }
        }

        private void btnAbout_Click(object sender, RibbonControlEventArgs e)
        {

            using (AboutBox aboutBox = new AboutBox())
            {
                aboutBox.ShowDialog();
            }

        }

        private void btnHistory_Click(object sender, RibbonControlEventArgs e)
        {
            if (Globals.ThisAddIn.m_SelectedOntologies != null && Globals.ThisAddIn.m_SelectedOntologies.Count > 0)
            {
                using (DownloadHistory downloadHistory = new DownloadHistory())
                {
                    downloadHistory.ShowDialog();
                }
            }
            else
                MessageBox.Show(Properties.Resources.NO_DOWNLOADITEMS_MESSAGE);

        }

        private void tbParse_Click(object sender, RibbonControlEventArgs e)
        {
            if (Globals.ThisAddIn.IsTermRecognitionOn == false)
            {
                ParseOn();
                Globals.ThisAddIn.IsTermRecognitionOn = true;
            }
            else
            {
                ParseOff();
                Globals.ThisAddIn.IsTermRecognitionOn = false;
            }
        }

        private void tbHighlight_Click(object sender, RibbonControlEventArgs e)
        {
            if (tbHighlight.Checked)
                SetHighLighting();
            else
                UndoHighlighting();
        }

        private void MakeSmartTags(string ont_Name, string ont_Format)
        {
            string FileName = string.Empty;
            string oboFilName = Path.Combine(Biolit_Settings.Settings.OBO_DWNLDS, ont_Name + "." + ont_Format.ToLower());
            FileName = Path.Combine(Biolit_Settings.Settings.OBO_DWNLDS, ont_Name + ".dat");
            CacheManager.CreateNewPersistentCache(oboFilName, FileName, ont_Name);
        }
        private void BackgroundOntologyDownload()
        {
            if (chkUpdate.Checked)
            {
                if (Globals.ThisAddIn.m_SelectedOntologies == null || Globals.ThisAddIn.m_SelectedOntologies.Count == 0)
                    return;
                foreach (OntList onlist in Globals.ThisAddIn.m_SelectedOntologies)
                {
                    if (!onlist.Source.Equals(LocalString, StringComparison.CurrentCultureIgnoreCase))
                    {
                        string URL = string.Empty;
                        if (!String.IsNullOrEmpty(onlist.Version) && !String.IsNullOrEmpty(onlist.ID))
                        {
                            URL = DownloadURL + onlist.ID.ToString();
                            _docNavigator = new XPathDocument(URL);
                            _navigator = _docNavigator.CreateNavigator();
                            _nodeIterator = _navigator.Select(NodePath);
                            while (_nodeIterator.MoveNext())
                            {
                                XPathNavigator versionNumber = _nodeIterator.Current.SelectSingleNode(VersionNumber);

                                if (versionNumber != null)
                                {
                                    ontologyList = new OntList(_nodeIterator.Current.SelectSingleNode(DisplayLabel).Value, _nodeIterator.Current.SelectSingleNode(IDLabel).Value, _nodeIterator.Current.SelectSingleNode(VersionNumber).Value, _nodeIterator.Current.SelectSingleNode("format").Value, SourceName);
                                }

                            };

                            if (ontologyList != null)
                                presentVersion = ontologyList.Version;

                            if (!String.IsNullOrEmpty(presentVersion))
                            {
                                try
                                {
                                    System.Version downloadVer = new Version(onlist.Version);
                                    System.Version currentVer = new Version(presentVersion);
                                    if (currentVer > downloadVer)
                                    {

                                        URL = Biolit_Settings.Settings.SelectedDownloadURL.URL;
                                        string dwnldPath = Biolit_Settings.Settings.OBO_DWNLDS;
                                        if (String.IsNullOrEmpty(URL) || String.IsNullOrEmpty(dwnldPath)) return;
                                        RestClient rc = new RestClient();
                                        string url = URL + @"/" + onlist.ID;
                                        string Status = null;
                                        string ontData = rc.GET(url, ref Status);
                                        if (ontData != null)
                                        {
                                            string FileName = onlist.Name + @"." + onlist.Format.ToLower();
                                            File.WriteAllText(Path.Combine(dwnldPath, FileName), ontData);
                                            MakeSmartTags(onlist.Name, onlist.Format);
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Debug.WriteLine(ex.Message, ExceptionTitle);
                                }
                            }
                        }
                    }
                }
            }
        }

        private void chkUpdate_Click(object sender, RibbonControlEventArgs e)
        {
            ConfigSettings cs = Biolit_Settings.Settings;
            if (chkUpdate.Checked)
            {
                cs.ontologiesUpdate = true;
                Thread threadUpdate = new Thread(this.BackgroundOntologyDownload);
                threadUpdate.IsBackground = true;
                threadUpdate.Start();
                while (threadUpdate.IsAlive == true)
                {
                    Application.DoEvents();
                }
            }
            else
                cs.ontologiesUpdate = false;
            Biolit_Settings.StoreSettings();
        }

        private void btnDwnldSettings_Click(object sender, RibbonControlEventArgs e)
        {
            using (DownloadsSettings downloadsSettings = new DownloadsSettings())
            {
                downloadsSettings.ShowDialog();
            }
        }
    }
}
